package com.dynamicthreadpool.example;

import com.dynamicthreadpool.core.DynamicThreadPool;
import com.dynamicthreadpool.dubbo.DynamicThreadPoolFactory;
import com.dynamicthreadpool.manager.ThreadPoolManager;
import com.dynamicthreadpool.spi.URL;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;

/**
 * 动态线程池URL使用样例
 * 演示如何通过URL配置和管理动态线程池
 */
public class DynamicThreadPoolURLExample {

    public static void main(String[] args) throws InterruptedException {
        System.out.println("=== 动态线程池URL使用样例 ===");
        
        // 演示1：使用DynamicThreadPoolFactory通过URL创建线程池
        useDynamicThreadPoolFactory();
        
        // 演示2：使用ThreadPoolManager结合URL管理线程池
        useThreadPoolManager();
        
        // 演示3：使用不同的队列类型和拒绝策略配置
        useDifferentConfigurations();
    }

    /**
     * 演示使用DynamicThreadPoolFactory通过URL创建线程池
     */
    private static void useDynamicThreadPoolFactory() throws InterruptedException {
        System.out.println("=== 演示1：使用DynamicThreadPoolFactory通过URL创建线程池 ===");
        
        // 创建URL对象，配置线程池参数
        Map<String, String> parameters = new HashMap<>();
        parameters.put("corethreads", "5");
        parameters.put("maxthreads", "10");
        parameters.put("queues", "100");
        parameters.put("keepalive", "60000");
        parameters.put("queueType", "LinkedBlockingQueue");
        parameters.put("rejectPolicy", "abort");
        parameters.put("threadname", "factory-example-pool");
        URL url = new URL("dynamic", "localhost", 8080, null, parameters);
        
        System.out.println("创建URL配置: " + url);
        
        // 使用工厂创建线程池
        DynamicThreadPoolFactory factory = new DynamicThreadPoolFactory();
        DynamicThreadPool threadPool = (DynamicThreadPool) factory.getExecutor(url);
        System.out.println("创建的线程池: " + threadPool);
        
        // 提交任务测试
        submitTasks(threadPool, 5, "factory");
        
        // 等待一段时间，让任务执行
        Thread.sleep(1000);
        
        // 动态更新线程池参数
        Map<String, String> updateParams = new HashMap<>(url.getParameters());
        updateParams.put("corethreads", "8");
        updateParams.put("maxthreads", "15");
        updateParams.put("queues", "200");
        updateParams.put("rejectPolicy", "callerruns");
        URL updateUrl = new URL(url.getProtocol(), url.getHost(), url.getPort(), url.getPath(), updateParams);
        
        System.out.println("\n更新URL配置: " + updateUrl);
        DynamicThreadPoolFactory.updateThreadPool(threadPool, updateUrl);
        System.out.println("更新后的线程池: " + threadPool);
        
        // 再次提交任务测试
        submitTasks(threadPool, 3, "factory-updated");
        
        // 等待一段时间，让任务执行
        Thread.sleep(1000);
        
        // 关闭线程池
        threadPool.shutdown();
        System.out.println("关闭线程池");
        System.out.println();
    }

    /**
     * 演示使用ThreadPoolManager结合URL管理线程池
     */
    private static void useThreadPoolManager() throws InterruptedException {
        System.out.println("=== 演示2：使用ThreadPoolManager结合URL管理线程池 ===");
        
        // 获取线程池管理器实例
        ThreadPoolManager manager = ThreadPoolManager.getInstance();
        
        // 创建URL对象
        Map<String, String> parameters = new HashMap<>();
        parameters.put("corethreads", "3");
        parameters.put("maxthreads", "8");
        parameters.put("queues", "50");
        parameters.put("keepalive", "30000");
        parameters.put("queueType", "ArrayBlockingQueue");
        parameters.put("rejectPolicy", "discard");
        parameters.put("threadname", "manager-example-pool");
        URL url = new URL("dynamic", "localhost", 8080, null, parameters);
        
        // 使用DynamicThreadPoolFactory创建线程池
        DynamicThreadPoolFactory factory = new DynamicThreadPoolFactory();
        DynamicThreadPool threadPool = (DynamicThreadPool) factory.getExecutor(url);
        
        // 注册线程池到管理器
        String poolKey = "example-threadpool";
        manager.registerThreadPool(poolKey, threadPool);
        System.out.println("注册线程池: " + poolKey);
        
        // 获取并使用线程池
        DynamicThreadPool registeredThreadPool = (DynamicThreadPool) manager.getThreadPool(poolKey);
        if (registeredThreadPool != null) {
            DynamicThreadPool pool = registeredThreadPool;
            System.out.println("从管理器获取的线程池: " + pool);
            
            // 提交任务
            submitTasks(pool, 4, "manager");
            
            // 等待任务执行
            Thread.sleep(500);
            
            // 使用URL动态更新线程池
            Map<String, String> updateParams = new HashMap<>(url.getParameters());
            updateParams.put("corethreads", "6");
            updateParams.put("maxthreads", "12");
            updateParams.put("queueType", "LinkedBlockingQueue");
            updateParams.put("rejectPolicy", "discardoldest");
            URL updateUrl = new URL(url.getProtocol(), url.getHost(), url.getPort(), url.getPath(), updateParams);
            
            System.out.println("\n更新线程池参数");
            manager.updateThreadPool(poolKey, updateUrl);
            System.out.println("更新后的线程池: " + pool);
            
            // 再次提交任务
            submitTasks(pool, 3, "manager-updated");
            Thread.sleep(500);
        }
        
        // 注销并关闭线程池
        manager.unregisterThreadPool(poolKey);
        System.out.println("注销线程池: " + poolKey);
        System.out.println();
    }

    /**
     * 演示使用不同的队列类型和拒绝策略创建线程池
     */
    private static void useDifferentConfigurations() throws InterruptedException {
        System.out.println("=== 演示3：使用不同的队列类型和拒绝策略配置 ===");
        
        // 定义不同的配置组合
        String[][] configs = {
            {"LinkedBlockingQueue", "abort"},
            {"ArrayBlockingQueue", "discard"},
            {"LinkedBlockingQueue", "discardoldest"},
            {"ArrayBlockingQueue", "callerruns"}
        };
        
        for (int i = 0; i < configs.length; i++) {
            String queueType = configs[i][0];
            String rejectPolicy = configs[i][1];
            
            try {
                // 创建URL配置
                Map<String, String> parameters = new HashMap<>();
                parameters.put("corethreads", "3");
                parameters.put("maxthreads", "8");
                parameters.put("queues", "50");
                parameters.put("queueType", queueType);
                parameters.put("rejectPolicy", rejectPolicy);
                parameters.put("threadname", "config-pool-" + i);
                URL url = new URL("dynamic", "localhost", 8080, null, parameters);
                
                // 创建线程池
                DynamicThreadPoolFactory factory = new DynamicThreadPoolFactory();
                DynamicThreadPool threadPool = (DynamicThreadPool) factory.getExecutor(url);
                System.out.println("创建配置[" + i + "]: 队列=" + queueType + ", 拒绝策略=" + rejectPolicy);
                System.out.println("线程池: " + threadPool);
                
                // 提交测试任务
                submitTasks(threadPool, 5, "config-" + i);
                
                // 等待任务完成
                Thread.sleep(500);
                
                // 关闭线程池
                threadPool.shutdown();
                System.out.println("关闭配置[" + i + "]的线程池\n");
            } catch (Exception e) {
                System.err.println("配置[" + i + "]创建失败: " + e.getMessage());
            }
        }
    }

    /**
     * 提交任务到线程池
     */
    private static void submitTasks(java.util.concurrent.ThreadPoolExecutor threadPool, int taskCount, String prefix) {
        System.out.println("提交" + taskCount + "个任务到" + prefix + "线程池");
        
        for (int i = 0; i < taskCount; i++) {
            final int taskId = i;
            threadPool.submit(() -> {
                try {
                    System.out.println(prefix + "任务 " + taskId + " 开始执行，线程: " + Thread.currentThread().getName());
                    // 模拟任务执行
                    Thread.sleep(500);
                    System.out.println(prefix + "任务 " + taskId + " 执行完成");
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            });
        }
    }
}